package com.yungam.imcs.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yungam.common.bean.alarm.AlarmDto;
import com.yungam.common.bean.equip.Equipment;
import com.yungam.common.bean.message.Message;
import com.yungam.common.service.AlarmService;
import com.yungam.common.service.EquipmentService;
import com.yungam.common.service.MessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author liuyicheng
 * @description: 定时将未处理的告警转为消息发给指定人
 */
@Slf4j
@Component
public class MessageJob {

    @Resource
    private AlarmService alarmService;
    @Resource
    private MessageService messageService;
    @Resource
    private EquipmentService equipmentService;

    /**
     * 每天凌晨12:30分执行
     * 消息分为三类: (以时间为划分条件)
     *      您有1001条告警超过一天未处理, 请尽快处理。
     *      您有120条告警超过三天未处理, 请尽快处理。
     *      您有10条告警超过一周未处理, 将转发您的上级。
     */
    @Scheduled(cron = "0 30 0 * * ?")
    public void transformAlarm() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        log.info("现在的时间是: {}, 开始执行自动任务, 将超过一天未处理的告警转为消息", now.format(df));
        long milliSeconds = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long max = milliSeconds - 1000 * 60 * 60 * 24 + 1000 * 60 * 30;
        QueryWrapper<AlarmDto> queryWrapper = new QueryWrapper<>();
        queryWrapper.le("timestamp", max)
                .eq("state", 0);
        // 获取超过一天未处理的告警
        List<AlarmDto> list = alarmService.list(queryWrapper);
        // 找到各个设备对应的人, 存入 map<ip, userId>
        Map<String, Integer> map = Maps.newHashMap();
        List<Equipment> equipmentList = equipmentService.list(new QueryWrapper<Equipment>()
                .select(Equipment.class, col -> !Objects.equals(col.getProperty(), "equ_img"))
                .isNotNull("equ_ip")
                .isNotNull("cur_user_id"));
        for (Equipment equip : equipmentList) map.put(equip.getEquIp(), equip.getCurUserId());

        // 按照人员 & 消息级别 分类
        long three = max - 1000 * 60 * 60 * 24 * 2, seven = max - 1000 * 60 * 60 * 24 * 6;
        Map<Integer, Integer[]> cntSum = Maps.newHashMap();
        for (AlarmDto alarm : list) {
            if (!map.containsKey(alarm.getIp())) continue;
            int key = map.get(alarm.getIp());
            Integer[] cnt = cntSum.getOrDefault(key, new Integer[]{0, 0, 0});
            if (alarm.getTimestamp() > three) cnt[0]++;
            else if (alarm.getTimestamp() > seven) cnt[1]++;
            else cnt[2]++;
            cntSum.put(key, cnt);
        }

        List<Message> messages = Lists.newArrayList();
        for (int id : cntSum.keySet()) {
            Integer[] array = cntSum.get(id);
            if (array[0] > 0) {
                Message message = new Message();
                message.setContent("您有" + array[0] + "条告警超过一天未处理, 请尽快处理")
                        .setState(0)
                        .setSendTime(new Date())
                        .setAcceptManId(id);
                messages.add(message);
            }
            if (array[1] > 0) {
                Message message = new Message();
                message.setContent("您有" + array[1] + "条告警超过三天未处理, 请尽快处理")
                        .setState(0)
                        .setSendTime(new Date())
                        .setAcceptManId(id);
                messages.add(message);
            }
            if (array[2] > 0) {
                Message message = new Message();
                message.setContent("您有" + array[2] + "条告警超过一周未处理, 将转发您的上级")
                        .setState(0)
                        .setSendTime(new Date())
                        .setAcceptManId(id);
                messages.add(message);
            }
        }

        if (messages.size() > 0) {
            for (Message message : messages) {
                messageService.save(message);
            }
            log.info("任务结束, 共有{}条告警超时未处理, 已成功转为消息发送指定人员！", messages.size());
            return;
        }
        log.info("任务结束, 没有告警超时未处理！");
    }
}
